package app1.rapidsquare.com.database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import org.apache.http.entity.StringEntity;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.TimeZone;

import app1.rapidsquare.com.classes.User;
import app1.rapidsquare.com.classes.Events;
import app1.rapidsquare.com.Utility.Utility;

/**
 * Created by Hikmat on 14.08.2014.
 */
public class AgileEventsProvider extends AgileSyncHelper<Events> implements IAgileProvider<Events> {

    // TABLE

    public static final String TABLE_NAME = "Events";

    // COLUMNS

    public static final String ID = "Id";
    public static final String TOPIC = "Topic";
    public static final String INTRODUCTION = "Introduction";
    public static final String AUTHOR = "Author";
    public static final String ROOM = "Room";
    public static final String START_TIME = "StartTime";
    public static final String END_TIME = "EndTime";
    public static final String AUTHOR_IMAGE_URL = "AuthorImageUrl";
    public static final String MODIFIED_DATE = "ModifiedDate";
    public static final String IS_DELETE = "IsDelete";

    public static final String IS_CHECKIN = "IsCheckIn";
    public static final String USER_RATING = "UserRating";
    public static final String AVG_RATING = "AvgRating";

    public AgileEventsProvider(Context context) {
        super(context, Events.class);
    }

    @Override
    public synchronized Events SelectById(int id) {
        Events event = null;
        try {
            SQLiteDatabase sqliteDataBase = getSqliteHelper().getReadableDatabase();
            if (sqliteDataBase.isOpen()) {

                String mQuery = " SELECT * FROM [Events] WHERE Id= "
                        + id
                        + " and IsDelete=0 ";

                Cursor mCursor = sqliteDataBase.rawQuery(mQuery, null);

                if (mCursor.getCount() < 1) {
                    if (!mCursor.isClosed())
                        mCursor.close();

                    sqliteDataBase.close();

                    Close();

                    return null;
                }

                mCursor.moveToFirst();

                do {

                    event = new Events();

                    event.Id = mCursor.getInt(mCursor.getColumnIndex(ID));
                    event.Topic = mCursor.getString(mCursor
                            .getColumnIndex(TOPIC));
                    event.Introduction = mCursor.getString(mCursor
                            .getColumnIndex(INTRODUCTION));
                    event.Author = mCursor.getString(mCursor
                            .getColumnIndex(AUTHOR));
                    event.Room = (mCursor
                            .getString(mCursor.getColumnIndex(ROOM)));
                    event.StartTime = Utility.getUTCDateFormat().parse(mCursor.getString(mCursor
                            .getColumnIndex(START_TIME)));
                    event.EndTime = Utility.getUTCDateFormat().parse(mCursor.getString(mCursor
                            .getColumnIndex(END_TIME)));

                    event.AuthorImageUrl = mCursor.getString(mCursor
                            .getColumnIndex(AUTHOR_IMAGE_URL));

                    event.IsCheckIn = mCursor.getInt(mCursor
                            .getColumnIndex(IS_CHECKIN)) > 0;
                    event.UserRating = mCursor.getDouble(mCursor
                            .getColumnIndex(USER_RATING));
                    event.AvgRating = mCursor.getDouble(mCursor
                            .getColumnIndex(AVG_RATING));

                } while (mCursor.moveToNext());

                if (!mCursor.isClosed())
                    mCursor.close();

                sqliteDataBase.close();
            }

            Close();
        } catch (Exception ex) {
            Utility.Log("AgileEventsProvider -> SelectById ", ex);
        }

        return event;
    }

    @Override
    public synchronized void Update() {
        try {
            SQLiteDatabase sqliteDataBase = getSqliteHelper().getReadableDatabase();

            if (sqliteDataBase.isOpen()) {

                String lastModifiedDate = "2012-10-08 06:43:05";

                Cursor c = sqliteDataBase.query(TABLE_NAME, new String[]{ID,
                        MODIFIED_DATE}, null, null, null, null, MODIFIED_DATE
                        + " desc");

                if (c.getCount() > 0) {
                    c.moveToFirst();
                    lastModifiedDate = c.getString(
                            c.getColumnIndex(MODIFIED_DATE)).trim();
                }
                if (!c.isClosed())
                    c.close();


                User userSession = Utility.getUserSession(mContext);
                if (userSession != null && !Utility.isNullOrEmpty(userSession.UserToken) && !userSession.IsUpdate) {
                    lastModifiedDate = "2012-10-08 06:43:05";
                    userSession.IsUpdate = true;
                }

                Utility.setUserSession(mContext, userSession);

                sqliteDataBase.close();

                setURL(Utility.EVENTS_SYNC_URL);

                JSONObject postObject = new JSONObject();
                postObject.put("UserToken", getUserToken());
                postObject.put("ModifiedDate", lastModifiedDate);

                this.httpEntity = new StringEntity(postObject.toString());

                RunSync();
            }

            Close();
        } catch (Exception e) {
            Utility.Log("AgileEventsProvider -> Update ", e);
        }
    }

    @Override
    public synchronized void Close() {
        if (getSqliteHelper() != null)
            getSqliteHelper().close();
    }

    public synchronized ArrayList<Events> SelectWithPaging(int startNumber, boolean isPast) {

        LinkedList<Events> mEventsList = new LinkedList<Events>();
        try {
            SQLiteDatabase sqliteDataBase = getSqliteHelper().getReadableDatabase();
            if (sqliteDataBase.isOpen()) {

                String mQuery;
                if (isPast) {
                    mQuery = " SELECT * FROM (SELECT * FROM [Events] WHERE EndTime<DATETIME('now') and IsDelete=0 "
                            + " ORDER BY [EndTime] DESC LIMIT "
                            + startNumber
                            + ",10) ORDER BY [EndTime]";
                } else {
                    mQuery = " SELECT * FROM [Events] WHERE StartTime>DATETIME('now','-4 hours') and IsDelete=0 "
                            + " ORDER BY [StartTime] LIMIT "
                            + startNumber
                            + ",10";
                }


                Cursor mCursor = sqliteDataBase.rawQuery(mQuery, null);

                if (mCursor.getCount() < 1) {
                    if (!mCursor.isClosed())
                        mCursor.close();

                    sqliteDataBase.close();
                    Close();
                    return new ArrayList<Events>(mEventsList);
                }

                mCursor.moveToFirst();
                LinkedList<String> headerList = new LinkedList<String>();

                do {
                    try {
                        Events events = new Events();
                        events.Id = mCursor.getInt(mCursor.getColumnIndex(ID));
                        events.Topic = mCursor.getString(mCursor
                                .getColumnIndex(TOPIC));
                        events.Introduction = mCursor.getString(mCursor
                                .getColumnIndex(INTRODUCTION));
                        events.Author = mCursor.getString(mCursor
                                .getColumnIndex(AUTHOR));
                        events.Room = mCursor.getString(mCursor
                                .getColumnIndex(ROOM));

                        events.StartTime = Utility.getUTCDateFormat().parse(mCursor.getString(mCursor
                                .getColumnIndex(START_TIME)));
                        events.EndTime = Utility.getUTCDateFormat().parse(mCursor.getString(mCursor
                                .getColumnIndex(END_TIME)));

                        events.AuthorImageUrl = mCursor.getString(mCursor
                                .getColumnIndex(AUTHOR_IMAGE_URL));
                        events.ModifiedDate = Utility.getUTCDateFormat().parse(mCursor.getString(mCursor
                                .getColumnIndex(MODIFIED_DATE)));
                        Integer isDelete = mCursor.getInt(mCursor
                                .getColumnIndex(IS_DELETE));

                        events.IsDelete = isDelete != null
                                && !isDelete.equals(0) ? true : false;

                        Integer isCheckIn = mCursor.getInt(mCursor
                                .getColumnIndex(IS_CHECKIN));
                        events.IsCheckIn = isCheckIn != null
                                && !isCheckIn.equals(0) ? true : false;
                        events.UserRating = mCursor.getDouble(mCursor
                                .getColumnIndex(USER_RATING));
                        events.AvgRating = mCursor.getDouble(mCursor
                                .getColumnIndex(AVG_RATING));

                        Date headerDate = Utility.getUTCDateFormat().parse(mCursor.getString(
                                mCursor.getColumnIndex(START_TIME)).trim());

                        dateSimpleFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
                        String headerText = dateSimpleFormat.format(headerDate).trim();

                        events.Header = "";

                        if (!headerList.contains(headerText)) {
                            Events headerEvent = new Events();
                            headerEvent.Header = headerText;
                            headerEvent.StartTime = events.StartTime;
                            headerList.add(headerText);
                            mEventsList.add(headerEvent);
                            /*if (isPast) {
                                if (headerList.size() == 0)
                                    mEventsList.addFirst(headerEvent);
                                else
                                    mEventsList.add(headerEvent);
                            }

                            headerList.add(headerText);

                            if (!isPast)
                                mEventsList.addFirst(headerEvent);*/
                        }

                        mEventsList.add(events);

                    } catch (Exception ex) {
                        continue;
                    }

                } while (mCursor.moveToNext());

                if (!mCursor.isClosed())
                    mCursor.close();

                sqliteDataBase.close();
            }

            Close();

        } catch (Exception ex) {
            Utility.Log("AgileEventsProvider -> SelectWithPaging ", ex);
        }
        return new ArrayList<Events>(mEventsList);
    }

    @Override
    protected synchronized void UpdateData(ArrayList<Events> resultList) {

        try {

            SQLiteDatabase sqliteDataBase = getSqliteHelper().getWritableDatabase();

            if (sqliteDataBase.isOpen()) {

                for (Events event : resultList) {

                    ContentValues values = new ContentValues();
                    values.put(ID, event.Id);
                    values.put(TOPIC, event.Topic);
                    values.put(INTRODUCTION, event.Introduction);
                    values.put(AUTHOR, event.Author);
                    values.put(ROOM, event.Room);
                    values.put(START_TIME, Utility.getUTCDateFormat().format(event.StartTime));
                    values.put(END_TIME, Utility.getUTCDateFormat().format(event.EndTime));
                    values.put(AUTHOR_IMAGE_URL, event.AuthorImageUrl);
                    values.put(MODIFIED_DATE, Utility.getUTCDateFormat().format(event.ModifiedDate));
                    values.put(IS_DELETE, event.IsDelete ? 1 : 0);
                    values.put(IS_CHECKIN, event.IsCheckIn ? 1 : 0);
                    values.put(USER_RATING, event.UserRating);
                    values.put(AVG_RATING, event.AvgRating);

                    long rowId = -1;

                    Cursor c = sqliteDataBase.query(TABLE_NAME, null, ID + "='"
                            + event.Id + "'", null, null, null, null);

                    if (c.getCount() > 0) {

                        rowId = sqliteDataBase.updateWithOnConflict(TABLE_NAME,
                                values, ID + "='" + event.Id + "'", null, 5);

                    } else {

                        rowId = sqliteDataBase.insertWithOnConflict(TABLE_NAME,
                                null, values, 5);
                    }

                    if (!c.isClosed())
                        c.close();

                    if (rowId < 0) {
                        Utility.Info("AgileEventsProviser", " is not inserted or updated");
                    }
                }

                sqliteDataBase.close();
            }

            Close();

        } catch (Exception e) {
            Utility.Log("AgileEventsProvider -> UpdateData ", e);
        }
    }

    @Override
    protected synchronized void Delete() {
        try {

            SQLiteDatabase sqliteDataBase = getSqliteHelper().getReadableDatabase();

            if (sqliteDataBase.isOpen()) {
                sqliteDataBase.delete(TABLE_NAME, "IsDelete=1", null);
                sqliteDataBase.close();
            }
            Close();
        } catch (Exception e) {
            Utility.Log("AgileEventsProviser - > DELETE ", e);
        }
    }

    public boolean CheckEventToCheckIn(Events event) {
        try {
            SimpleDateFormat simpleDateFormat = Utility.getUTCDateFormat();

            SQLiteDatabase sqliteDataBase = getSqliteHelper().getReadableDatabase();
            if (sqliteDataBase.isOpen()) {

                String mQuery = " SELECT * FROM [Events] WHERE (StartTime<='" + simpleDateFormat.format(event.StartTime) + "' and EndTime>='" + simpleDateFormat.format(event.StartTime) + "' " +
                        "or StartTime<='" + simpleDateFormat.format(event.EndTime) + "' and EndTime>='" + simpleDateFormat.format(event.EndTime) + "') and IsDelete=0 and IsCheckIn=1";

                Cursor mCursor = sqliteDataBase.rawQuery(mQuery, null);

                if (mCursor.getCount() < 1) {
                    if (!mCursor.isClosed())
                        mCursor.close();

                    sqliteDataBase.close();

                    Close();

                    return false;
                }

                if (!mCursor.isClosed())
                    mCursor.close();

                sqliteDataBase.close();
            }

            Close();
        } catch (Exception ex) {
            Utility.Log("AgileEventsProvider -> CheckEventToCheckIn ", ex);
        }

        return true;
    }

    public void CheckInEvent(Events event) {
        try {

            SQLiteDatabase sqliteDataBase = getSqliteHelper().getWritableDatabase();

            if (sqliteDataBase.isOpen()) {

                ContentValues values = new ContentValues();
                values.put(ID, event.Id);
                values.put(TOPIC, event.Topic);
                values.put(INTRODUCTION, event.Introduction);
                values.put(AUTHOR, event.Author);
                values.put(ROOM, event.Room);
                values.put(START_TIME, Utility.getUTCDateFormat().format(event.StartTime));
                values.put(END_TIME, Utility.getUTCDateFormat().format(event.EndTime));
                values.put(AUTHOR_IMAGE_URL, event.AuthorImageUrl);
                values.put(MODIFIED_DATE, Utility.getUTCDateFormat().format(event.ModifiedDate));
                values.put(IS_DELETE, event.IsDelete ? 1 : 0);
                values.put(IS_CHECKIN, event.IsCheckIn ? 1 : 0);
                values.put(USER_RATING, event.UserRating);
                values.put(AVG_RATING, event.AvgRating);

                long rowId = -1;

                Cursor c = sqliteDataBase.query(TABLE_NAME, null, ID + "='"
                        + event.Id + "'", null, null, null, null);

                if (c.getCount() > 0) {

                    rowId = sqliteDataBase.updateWithOnConflict(TABLE_NAME,
                            values, ID + "='" + event.Id + "'", null, 5);

                }

                if (!c.isClosed())
                    c.close();

                if (rowId < 0) {
                    Utility.Info("AgileEventsProviser", " is not inserted or updated");
                }


                sqliteDataBase.close();
            }

            Close();

        } catch (Exception e) {
            Utility.Log("AgileEventsProvider -> CheckInEvent ", e);
        }
    }
}
